home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / dviware / umddvi / lib / font_subr.c < prev    next >
C/C++ Source or Header  |  1990-10-01  |  5KB  |  239 lines

  1. /*
  2.  * Copyright (c) 1987 University of Maryland Department of Computer Science.
  3.  * All rights reserved.  Permission to copy for any purpose is hereby granted
  4.  * so long as this copyright notice remains intact.
  5.  */
  6.  
  7. #ifndef lint
  8. static char rcsid[] = "$Header: font_subr.c,v 2.4 87/06/16 18:28:02 chris Exp $";
  9. #endif
  10.  
  11. /*
  12.  * Subroutines common to all fonts.
  13.  */
  14.  
  15. #include "font.h"
  16.  
  17. static struct glyph *freeglyphs;
  18.  
  19. char    *malloc();
  20. extern    errno;
  21.  
  22. /*
  23.  * Set up the font structures to note that a font has glyphs in
  24.  * the half-open interval [low, high).
  25.  *
  26.  * SHOULD I ALLOW ADDITIONS TO THE RANGE VIA SUBSEQUENT CALLS TO
  27.  * FontHasGlyphs?
  28.  */
  29. FontHasGlyphs(f, low, high)
  30.     register struct font *f;
  31.     register int low, high;
  32. {
  33.     register struct glyph **gp;
  34.  
  35.     /* record bounds */
  36.     f->f_lowch = low;
  37.     f->f_highch = high;
  38.  
  39.     /*
  40.      * Allocate space for all the glyph pointers, and set
  41.      * them all to NULL.
  42.      */
  43.     if (low >= high)    /* no glyphs */
  44.         gp = NULL;
  45.     else {
  46.         gp = (struct glyph **) malloc((unsigned) (high - low) *
  47.             sizeof (*gp));
  48.         if (gp == NULL)
  49.             return (-1);
  50.     }
  51.     f->f_glybase = gp;
  52.     f->f_gly = gp - low;
  53.     while (++low <= high)
  54.         *gp++ = NULL;
  55.     return (0);
  56. }
  57.  
  58. /*
  59.  * AllocGlyph allocates a new glyph.  ReleaseGlyph puts one onto the free
  60.  * list.  We maintain a local list of free glyphs.
  61.  */
  62. #define ReleaseGlyph(g)    \
  63.     ((g)->g_un.g_next = freeglyphs, freeglyphs = (g))
  64.  
  65. static struct glyph *
  66. AllocGlyph(n)
  67.     int n;
  68. {
  69.     register struct glyph *g;
  70.     register int i;
  71.  
  72.     if ((g = freeglyphs) == NULL) {
  73.         g = (struct glyph *) malloc((unsigned) (128 * sizeof (*g)));
  74.         if (g == NULL)
  75.             error(1, errno, "out of glyph memory");
  76.         g += (i = 128);
  77.         while (--i >= 0) {
  78.             g--;
  79.             ReleaseGlyph(g);
  80.         }
  81.     }
  82.     freeglyphs = g->g_un.g_next;
  83.     g->g_flags = 0;
  84.     g->g_raster = NULL;
  85.     g->g_index = n;
  86.     return (g);
  87. }
  88.  
  89. /*
  90.  * Free one glyph.
  91.  */
  92. void
  93. FreeGlyph(f, n)
  94.     struct font *f;
  95.     register int n;
  96. {
  97.     register struct glyph *g;
  98.  
  99.     if (n < f->f_lowch || n >= f->f_highch)
  100.         return;
  101. #ifdef notdef
  102.     (*f->f_ops->fo_freegly)(f, n, n);
  103. #endif
  104.     if ((g = f->f_gly[n]) == NULL)
  105.         return;
  106.     if (g->g_raster != NULL)
  107.         free(g->g_raster);
  108.     ReleaseGlyph(g);
  109. }
  110.  
  111. /*
  112.  * Free a font.
  113.  */
  114. void
  115. FreeFont(f)
  116.     register struct font *f;
  117. {
  118.     register struct glyph *g;
  119.     register int i;
  120.  
  121. #ifdef notdef
  122.     (*f->f_ops->fo_freegly)(f, f->f_lowch, f->f_highch);
  123. #endif
  124.     for (i = f->f_lowch; i < f->f_highch; i++) {
  125.         if ((g = f->f_gly[i]) == NULL)
  126.             continue;
  127.         if (g->g_raster != NULL)
  128.             free(g->g_raster);
  129.         ReleaseGlyph(g);
  130.     }
  131.     if (f->f_glybase != NULL)
  132.         free((char *) f->f_glybase);
  133.     (*f->f_ops->fo_freefont)(f);
  134.     free(f->f_path);
  135.     free(f->f_font);
  136.     free((char *) f);
  137. }
  138.  
  139. /*
  140.  * Get glyph `c' in font `f'.  We pull in a few adjacent glyphs here
  141.  * under the (perhaps naive) assumption that things will go faster
  142.  * that way.
  143.  *
  144.  * TODO:
  145.  *    try different adjacency values
  146.  *    make adjacency a font attribute? (or an op)
  147.  */
  148. #define    ADJ    8        /* must be a power of 2 */
  149. #define    GET_ADJ(c, l, h) ((h) = ADJ + ((l) = (c) & ~(ADJ - 1)))
  150.  
  151. struct glyph *
  152. GetGlyph(f, c)
  153.     register struct font *f;
  154.     int c;
  155. {
  156.     register int i, h, l;
  157.  
  158.     GET_ADJ(c, l, h);
  159.     if (l < f->f_lowch)
  160.         l = f->f_lowch;
  161.     if (h > f->f_highch)
  162.         h = f->f_highch;
  163.     if (l >= h)
  164.         return (NULL);
  165.     for (i = l; i < h; i++)
  166.         if (f->f_gly[i] == NULL)
  167.             f->f_gly[i] = AllocGlyph(i);
  168.  
  169.     if ((*f->f_ops->fo_getgly)(f, l, h)) {
  170.         /*
  171.          * I do not know what to do about this just yet, so:
  172.          */
  173.         panic("getgly fails and I am confused ... help!");
  174.     }
  175.  
  176.     /*
  177.      * Apply the appropriate scale factor to the TFM widths.
  178.      * This makes them come out in scaled points, instead of FIXes.
  179.      */
  180.     ScaleGlyphs(f, l, h);    /* ??? */
  181.  
  182.     return (f->f_gly[c]);
  183. }
  184.  
  185. /*
  186.  * Get the raster for glyph g in font f at rotation r.
  187.  */
  188. char *
  189. GetRaster(g, f, r)
  190.     register struct glyph *g;
  191.     register struct font *f;
  192.     int r;
  193. {
  194.     int l, h;
  195.  
  196.     /* abort if caller did not ask for rasters in advance */
  197.     if ((f->f_flags & FF_RASTERS) == 0)
  198.         panic("GetRaster(%s)", f->f_path);
  199.  
  200.     /*
  201.      * If there is no raster, get one.  Blank characters,
  202.      * however, never have rasters.
  203.      */
  204.     if (g->g_raster == NULL) {
  205.         if (!HASRASTER(g))
  206.             return (NULL);
  207.         /*
  208.          * THE FOLLOWING DEPENDS ON THE ADJACENCY MATCHING THAT IN
  209.          * GetGlyph() ABOVE.
  210.          */
  211.         GET_ADJ(g->g_index, l, h);
  212.         if (l < f->f_lowch)
  213.             l = f->f_lowch;
  214.         if (h > f->f_highch)
  215.             h = f->f_highch;
  216.         if ((*f->f_ops->fo_rasterise)(f, l, h))
  217.             error(1, 0, "rasterise fails (out of memory?)");
  218.     }
  219.     if (g->g_rotation != r)
  220.         SetRotation(g, r);
  221.     return (g->g_raster);
  222. }
  223.  
  224. /*
  225.  * Return a TeX-style font name, including scale factor.
  226.  * SHOULD I BOTHER WITH \magstep STYLE NAMES?
  227.  */
  228. char *
  229. Font_TeXName(f)
  230.     register struct font *f;
  231. {
  232.     static char result[200];
  233.  
  234.     if (f->f_scaled == 1000)
  235.         return (f->f_font);
  236.     sprintf(result, "%s scaled %d", f->f_font, f->f_scaled);
  237.     return (result);
  238. }
  239.